home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_6.2
/
DPP
/
DPP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
8KB
|
330 lines
/*
* dpp.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/*
* D(raw)P(oint)P(attern)
*
* generate and draw random point, square or disk pattern
*
*/
#include "dpp.h"
#define ON 1
#define OFF 0
#define NEW_SEED ON
#define SQR(a) ( (a)*(a) )
/* globals */
extern char *optarg;
extern int optind, opterr;
extern short tiffInput; /* flag=0 if no ImageIn to set tags; else =1 */
/*
* usage of routine
*/
void
usage (char *progname)
{
progname = last_bs (progname);
printf ("USAGE: %s outimg [-p t][-c f][-s x y] [-L]\n", progname);
printf ("\n%s generates and draws a random, ordered or clustered point pattern\n\n", progname);
printf ("ARGUMENTS:\n");
printf (" outimg: output image filename (TIF format)\n\n");
printf ("OPTIONS:\n");
printf (" -p t: select pattern type: R(andom), O(rdered), C(lustered)\n");
printf (" t = R: random (default)\n");
printf (" t = O: ordered\n");
printf (" t = C: clustered\n");
printf (" -c f: desired fractional coverage, 0<=f<=100\n");
printf (" -s x y: output image size (default 512x512)\n");
printf (" -L: print Software License for this module\n");
exit (1);
}
/*
* function to draw points
*/
void
draw_points (int *x, int *y, long n, struct Image *imgOut, int value)
{
int ip;
for (ip = 0; ip < n; ip++) {
setpixel (*(x + ip), *(y + ip), imgOut, value);
}
}
/*
* function to generate a single random point coordinate
*/
Sp
random_point (int nx, int ny)
{
Sp pt;
pt.x = (short) ((float) rand () * (float) nx / (float) RAND_MAX);
pt.y = (short) ((float) rand () * (float) ny / (float) RAND_MAX);
return (pt);
}
/*
* function to generate random point coordinates
*/
void
generate_random_points (int *xc, int *yc, long npix, int nx, int ny)
{
int seed = 1;
int ip;
Sp pt;
if (NEW_SEED == ON) {
printf ("...select new seed(enter 1 to reinitialize):");
scanf ("%d", &seed);
}
srand (seed); /* must be called only once per series */
for (ip = 0; ip < npix; ip++) {
#ifdef DEBUG
if (ip % 100 == 0)
printf (" ip = %d\n", ip);
#endif
pt = random_point (nx, ny);
*(xc + ip) = (int) pt.x;
*(yc + ip) = (int) pt.y;
}
}
/*
* function to generate ordered point coordinates
*/
void
generate_ordered_points (int *xc, int *yc, long npix, int nx, int ny, float coverage)
{
int sepx;
int sepy;
int ix;
int iy;
int xnpts;
int ynpts;
int i;
if (!npix)
return;
xnpts = (int) ((float) nx * (float) sqrt ((double) coverage));
ynpts = (int) ((float) ny * (float) sqrt ((double) coverage));
sepx = (nx / xnpts) + 1;
sepy = (ny / ynpts) + 1;
i = 0;
for (ix = 0; ix < nx; ix += sepx) {
for (iy = 0; iy < ny; iy += sepy) {
if (i >= npix)
break;
*(xc + i) = ix;
*(yc + i) = iy;
i++;
}
}
}
/*
* function to generate clustered point coordinates
*/
void
generate_clustered_points (int *xc, int *yc, long npix, int nx, int ny, long nxny)
{
char buf[256];
long Nc;
int kc;
int ip;
int seed = 1;
Sp cur_seed_pt;
Sp new_pt;
int xsd, ysd;
int ppc;
double sigma;
double fxc, fyc;
double fac, rsq;
for (;;) {
printf ("How many clusters? ");
readlin (buf);
if (!(Nc = atol (buf)))
printf ("Sorry, invalid input, try again\n");
else
break;
}
for (;;) {
printf ("Select SIGMA to set cluster width (width proportional to NX/SIGMA): ");
readlin (buf);
if (!(sigma = (float) atof (buf)))
printf ("Sorry, invalid input, try again\n");
else
break;
}
if (NEW_SEED == ON) {
printf ("...select new seed(enter 1 to reinitialize):");
readlin (buf);
sscanf (buf, "%d", &seed);
}
srand (seed);
ppc = npix / Nc;
ip = 0;
for (kc = 0; kc < Nc; kc++) {
cur_seed_pt = random_point (nx, ny);
/*
* ** restrict seed coordinate to interior of available AOI
* ** (to reduce chance of generating a cluster overlapping edge of AOI)
*/
xsd = (int) ((nx / 2) + (2.0 * cur_seed_pt.x / nx - 1.0) * (nx / 8));
ysd = (int) ((ny / 2) + (2.0 * cur_seed_pt.y / ny - 1.0) * (ny / 8));
printf ("\ncluster: %d - seed point: %3d, %3d\n", kc, xsd, ysd);
do {
new_pt = random_point (nx, ny);
fxc = (double) (2.0 * new_pt.x / nx - 1.0);
fyc = (double) (2.0 * new_pt.y / ny - 1.0);
if ((rsq = SQR (fxc) + SQR (fyc)) < 1.0) {
fac = sqrt (-2.0 * log (rsq) / rsq);
*(xc + ip) = (int) (xsd + fac * fxc * (double) nx / (2 * sigma));
*(yc + ip) = (int) (ysd + fac * fyc * (double) ny / (2 * sigma));
//printf("\n%3d - (%3d, %3d)\n", ip, *(xc+ip), *(yc+ip));
ip++;
}
} while (ip < ppc * (kc + 1));
}
}
void
main (int argc, char **argv)
{
int i_arg;
char type = 'R'; /* type of pattern drawn */
int *xc, *yc;
float coverage;
long nxny;
long npix;
int nx = HEIGHT;
int ny = WIDTH;
struct Image *imgOut;
/*
* cmd line options
*/
static char *optstring = "p:c:s:L";
nxny = nx * ny;
coverage = (float) (5.0);
/*
* parse command line
*/
optind = 2;
opterr = ON; /* give error messages */
if (argc < 2)
usage (argv[0]);
while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
switch (i_arg) {
case 'c':
coverage = (float) atof (optarg);
break;
case 'p':
type = optarg[0];
break;
case 's':
if (!sscanf (argv[optind - 1], "%d", &nx) || !sscanf (argv[optind], "%d", &ny)) {
printf ("Error getting values for image size\n");
printf ("Will use defaults\n");
nx = WIDTH;
ny = HEIGHT;
}
else
optind += 1;
nxny = nx * ny;
break;
case 'L':
print_sos_lic ();
exit (0);
default:
printf ("...unknown command line option encountered\n");
exit (1);
break;
}
}
npix = (long) (coverage * nxny / 100.0);
printf ("Image size for %s = %d x %d pixels\n", argv[1], nx, ny);
printf ("Coverage = %f percent of area, # pixels to be drawn = %ld\n", coverage, npix);
printf ("pattern = %c\n", type);
/*
* initialize graphics
*/
imgOut = ImageAlloc ((long) ny, (long) nx, BPS);
/* reset tiffInput so that we write a grayscale file (i.e tags are not copied) */
tiffInput = 0;
if ((xc = (int *) calloc ((size_t) npix, sizeof (int))) == NULL) {
printf ("\n...mem alloc for xc failed\n");
exit (1);
}
if ((yc = (int *) calloc ((size_t) npix, sizeof (int))) == NULL) {
printf ("\n...mem alloc for yc failed\n");
exit (1);
}
switch (type) {
case 'R': /* Random point pattern */
case 'r':
generate_random_points (xc, yc, npix, nx, ny);
draw_points (xc, yc, npix, imgOut, WHITE);
break;
case 'O': /* Ordered point pattern */
case 'o':
generate_ordered_points (xc, yc, npix, nx, ny, coverage / (float) 100.0);
draw_points (xc, yc, npix, imgOut, WHITE);
break;
case 'C': /* Clustered point pattern */
case 'c':
generate_clustered_points (xc, yc, npix, nx, ny, nxny);
draw_points (xc, yc, npix, imgOut, WHITE);
break;
default:
printf ("...unknown pattern type: %c\n", type);
exit (1);
break;
}
/*
* free memory
*/
free (xc);
free (yc);
printf ("\n...writing output file %s\n", argv[1]);
ImageOut (argv[1], imgOut);
}